/**
 * 注意：使用await的方法必须加上async，不然会报错！！
 */
module.exports = {
  /**
   * 更新数据
   * @param {*} context 会话
   * @param {*} tableName  表名
   * @param {*} data  新数据
   * @result  data  结果为受影响的记录数
   */
 async updateBy_id(context,tableName,data){
  console.log("updateById:")
  console.log("tableName",tableName);
  console.log(data);
  console.log("_id",data._id);
  const _id = data._id;
  if(!_id){
    const msg = "data._id不存在，无法更新";
    console.log(msg);
    return {code:-1,msg:msg}
  }
  console.log("data",data);
  const cloud = context.cloud; 
  const result =await cloud.db.collection(tableName).updateMany(
   {_id:_id},
   {$set:data}
  );
  console.log("updateMany done, result:",result)
  return result;
 },
  /**
   * 更新数据（乐观锁）
   * @param {*} context 会话
   * @param {*} tableName  表名
   * @param {*} data  新数据
   * @result  data  结果为受影响的记录数 0代表修改不成功
   */
 async updateBy_idWithVersionLock(context,tableName,data){
  console.log("updateById:")
  console.log("tableName",tableName);
  let oldVersion = data.version;
  console.log("oldVersion:",oldVersion);
  console.log("_id",data._id);
  let newVersion;
  if(!oldVersion&&oldVersion!=0){
    oldVersion = 0;
    newVersion=0;
  }else{
    newVersion = oldVersion+1;
  }
  
  const _id = data._id;
  if(!_id){
    const msg = "data._id不存在，无法更新";
    console.log(msg);
    return {code:-1,msg:msg}
  }
  
  console.log("newVersion:",newVersion);
  data.version = newVersion;
  console.log("data",data);
  const cloud = context.cloud; 

  let filter = {_id:_id};
  if(newVersion!=0){
    filter.version = oldVersion;
  }

  const result =await cloud.db.collection(tableName).updateMany(
   filter,
   {$set:data}
  );
  console.log("updateMany done, result:",result)
  return result;
 },
 /**
  * 查找单条数据
  * @param {*} context 
  * @param {*} tableName 
  * @param {*} filter 
  * @result  返回单条数据或者null
  */
 async findOne(context,tableName,filter){
    console.log("findOne:")
    console.log("tableName",tableName);
    console.log("filter",filter);
    const cloud = context.cloud; 
    const result = await cloud.db.collection(tableName).find(
        filter, 
        {  
            limit: 1,  
        }
    );
    console.log("findOne done,result:",result)
    return result.length>0?result[0]:null;
 },
 /**
  * 查询列表
  * @param {*} context 
  * @param {*} tableName 
  * @param {*} filter 
  * @param {*} options 
  * filter	object	是	-	过滤条件
  * options.projection	object	否	-	查询后过滤的字段
  * options.sort	object	否	-	排序规则, key是field名字，value是1或-1
  * options.skip	number	否	-	跳过的文档数量
  * options.limit	number	否	-	查询的文档数量限
  * @result  返回列表
  */
 async find(context,tableName,filter,options){
    console.log("find:")
    console.log("tableName",tableName);
    console.log("filter",filter);
    const cloud = context.cloud; 
    const result = await cloud.db.collection(tableName).find(
        filter, 
        options
    );
    console.log("find done,result.length:",result.length);
    return result;
 },
 /**
  * 分页查询
  * @param {*} context 
  * @param {*} tableName 表名
  * @param {*} filter 过滤条件
  * @param {*} sort 排序条件（1为升序排列，而-1是用于降序排列）
  * @param {*} pageNum 当前页数 （默认1）
  * @param {*} pageSize 每页返回多少条数据 （默认10条）
  */
 async findPage(context,tableName,filter,sort,pageNum,pageSize){
    const cloud = context.cloud; 
    console.log("findPage:")
    console.log("tableName",tableName);
    console.log("filter",filter);
    console.log("sort",sort);
    if(!pageNum){
       pageNum=1;
    }
    if(!pageSize){
       pageSize=10;
    }
    //跳过多少条记录
    const skip = ((pageNum-1)*pageSize);
    //限制返回数量
    const limit = pageSize;
    //总记录数
    let total = await this.count(context,tableName,filter);
    //总页数(向上取整)
    let pageCount = Math.ceil(total/pageSize);
    const options = {sort,skip,limit};
    
    //返回当前集合
    let list = await this.find(context,tableName,filter,options);
    result={
       list,total,pageCount,pageSize,
    };
    console.log("find done,total:",total);
    return result;
 },
 /**
  * 查询所有
  * @param {*} context 
  * @param {*} tableName 表名
  * @param {*} filter 过滤条件
  * @param {*} sort 排序条件（1为升序排列，而-1是用于降序排列）
  */
 async findAll(context,tableName,filter,sort){
    console.log("findAll:")
    console.log("tableName",tableName);
    console.log("filter",filter);
    console.log("sort",sort);
    let result = [];
    let pageSize = 500;
    let page = await this.findPage(context,tableName,filter,sort,1,pageSize);
    let pageCount = page.pageCount;

    for(let pageNum=1;pageNum<=pageCount;pageNum++){
      // console.log("pageNum<=pageCount",pageNum<=pageCount)
      // console.log("当前页数:"+pageNum+"总页数:"+pageCount)
       page = await this.findPage(context,tableName,filter,sort,pageNum,pageSize);
       let list = page.list;
       if(list.length==0){
          break;
       }
       for(let item of list){
          result.push(item);
       }
    }
    return result;
 },
  /**
  * 获取集合中复合条件的记录数量
  * @param {*} context 
  * @param {*} filter 
  * @result  数据数量
  */
 async count(context,tableName,filter){
    console.log("count:")
    console.log("tableName",tableName);
    console.log("filter",filter);
    const cloud = context.cloud; 
    const result = await cloud.db.collection(tableName).count(filter);
    console.log("count done,result:",result)
    return result;
 },
 /**
  * 删除记录
  * @param {*} context 
  * @param {*} tableName 
  * @param {*} filter 
  * @result 返回结果为删除的记录数 返回对象
  */
 async deleteMany(context,tableName,filter){
    console.log("deleteMany:")
    console.log("tableName",tableName);
    console.log("filter",filter);
   const cloud = context.cloud; 
   const result = await cloud.db.collection(tableName).deleteMany(filter);
   console.log("deleteMany done,result:",result)
   return result;
 },
 /**
  * 插入数据
  * @param {*} data 
  * @result 结果为创建数据的_id
  */
 async insertOne(context,tableName,data){
    console.log("insertOne:")
    console.log("tableName",tableName);
    console.log("data",data);
    const cloud = context.cloud; 
    const result = await cloud.db.collection(tableName).insertOne(data);
    console.log("insertOne done,result:",result)
    data._id=result;
    return result;
 },
/**
 * 修改或者插入
 * @param {*} context 
 * @param {*} tableName 
 * @param {*} data 
 */
async insertOrUpdate(context,tableName,data){
   let result = null;
    if(data._id){
       //修改
     result = await this.updateBy_id(context,tableName,data);
    }else{
       //插入
      result = await this.insertOne(context,tableName,data);
    }

    return result;
 },
    /**
     * 聚合查询
     * @param {*} context 
     * @param {*} tableName 表名
     * @param {*} param 参数 {Object} 多余的条件不能传, '' 不能传入
     */
    async aggregate(context,tableName,pipeline){
        console.log("aggregate:")
        console.log("tableName",tableName);
        console.log("param",JSON.stringify(pipeline));
        const result = await context.cloud.db.collection(tableName).aggregate(pipeline);
        console.log("deleteOne is complete. result=" + result);
        return result;
    },
    
     async update(context, tableName, filter, data) {
      if (!filter) {
        const msg = "filter不存在，无法更新";
        console.info(msg);
        return { code: -1, msg: msg }
      }
      const cloud = context.cloud;
      const result = await cloud.db.collection(tableName).updateMany(
      filter,
      { $set: data }
      );
      console.info("updateMany done, result:", result)
      return result;
    }
}
